import type {
  ICreateCommentBody,
  IPostClientDetails,
  IRole,
} from '@/interfaces';
import type { TBody, TMetadata } from '@/types';
import useUser from '@/hooks/useUser';
import { type ChangeEvent, useEffect, useState } from 'react';
import {
  type InfiniteQueryObserverRefetchErrorResult,
  type InfiniteQueryObserverSuccessResult,
  useMutation,
  useQueryClient,
} from '@tanstack/react-query';
import useToast, { LoginReminderContent } from '@/hooks/useToast';
import { createComment } from '@/services/api';
import sanitizeHtml from 'sanitize-html';
import Image, { StaticImageData } from 'next/image';
import { getUserAvatar } from '@/lib/tool';
import Link from 'next/link';
import avatar from '@/public/images/avatar.png';
import { useTranslations } from 'use-intl';

export default function PostComment({
  query,
  postData,
  metadata,
}: {
  query:
    | InfiniteQueryObserverRefetchErrorResult<IPostClientDetails>
    | InfiniteQueryObserverSuccessResult<IPostClientDetails>;
  postData: IPostClientDetails;
  metadata: TMetadata;
}) {
  const env = metadata.env;
  const userQuery = useUser(metadata);
  const [commentContent, setCommentContent] = useState('');
  const queryClient = useQueryClient();
  const { show } = useToast();
  const t = useTranslations('PostIdPage');
  const [userInfo, setUserInfo] = useState<{
    id: any;
    alias: string;
    avatar: string | StaticImageData;
    roles: IRole[];
  }>({
    id: null,
    alias: t('anonymousHero'),
    avatar: avatar,
    roles: [],
  });

  const createCommentMutation = useMutation(
    async (variables: TBody<ICreateCommentBody>) => {
      await createComment(variables);
      await query.refetch({ throwOnError: true });
    },
  );

  useEffect(() => {
    if (userQuery.data && userQuery.data.user) {
      setUserInfo({
        id: userQuery.data.user.id,
        alias: userQuery.data.user.alias,
        avatar: getUserAvatar(userQuery.data.user, metadata).mediumAvatarUrl,
        roles: userQuery.data.user.roles,
      });
    }
  }, [metadata, userQuery.data]);

  async function onClickPostComment() {
    if (!userQuery.data?.user) {
      show({
        title: t('notLoggedInPrompt'),
        content: <LoginReminderContent />,
      });
      return;
    }

    const _commentContent = commentContent;
    if (!_commentContent) {
      show({
        type: 'DANGER',
        message: t('replyContentEmptyError'),
      });
      return;
    }

    const content = sanitizeHtml(_commentContent);
    if (!content) {
      show({
        type: 'DANGER',
        message: t('replyContentEmptyError'),
      });
      return;
    }

    try {
      const postId = postData.basic.id;
      await createCommentMutation.mutateAsync({
        data: {
          postId,
          content,
        },
      });

      setCommentContent('');
      show({
        type: 'SUCCESS',
        message: t('replyCompleted'),
      });
    } catch (e) {
      createCommentMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function onChangeCommentContent(e: ChangeEvent<HTMLTextAreaElement>) {
    setCommentContent(e.target.value);
  }

  return (
    <div className="row overflow-hidden">
      <div className="col-12 col-lg-2 d-none d-lg-block pe-0">
        <div
          className="card h-100 border-0 rounded-0 vstack gap-2"
          style={{
            borderBottomLeftRadius: '0.376rem !important',
          }}
        >
          <div
            className="align-self-center my-4"
            style={{ width: 128, height: 128 }}
          >
            <Image
              priority
              className="rounded-circle card-img-top"
              src={userInfo.avatar}
              alt={userInfo.alias}
              title={userInfo.alias}
              width={128}
              height={128}
              placeholder="blur"
              blurDataURL={env.APP_BLUR_DATA_URL}
              style={{
                maxWidth: '100%',
                objectFit: 'cover',
              }}
            />
          </div>
          <div className="card-body align-self-center text-center">
            <h5 className="card-title">
              <Link
                href={userInfo.id ? `/users/${userInfo.id}` : '/login'}
                className="text-reset link-underline-light link-offset-3 link-underline-opacity-0 link-underline-opacity-100-hover"
              >
                {userInfo.alias}
              </Link>
            </h5>

            <p className="card-text my-3">
              {userInfo.roles
                .filter((item) => !item.hide)
                .map((item) => item.name)
                .join(' / ')}
            </p>
          </div>
        </div>
      </div>
      <div className="col-auto border-1 px-0 border-secondary border-opacity-10 border-end"></div>
      <div className="col col-lg-9 flex-grow-1 ps-0">
        <div
          className="card border-0 border-secondary border-opacity-10 rounded-0 h-100"
          style={{
            borderBottomRightRadius: '0.376rem !important',
          }}
        >
          <div className="card-body">
            <textarea
              name="commentContent"
              className="form-control my-2"
              rows={7}
              placeholder={t('enterReply')}
              value={commentContent}
              onChange={onChangeCommentContent}
            ></textarea>
            <button
              disabled={createCommentMutation.isLoading || !commentContent}
              onClick={onClickPostComment}
              type="button"
              className="btn btn-outline-primary my-3 w-100"
            >
              {createCommentMutation.isLoading ? (
                <span
                  className="spinner-border spinner-border-sm me-2"
                  role="status"
                  aria-hidden="true"
                ></span>
              ) : (
                <i className="bi bi-cursor me-2"></i>
              )}
              {t('postReply')}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}
